package com.xquant.databasemanagement.service;

import com.xquant.databasemanagement.bean.CommonObject;
import com.xquant.databasemanagement.bean.DatabaseBean;
import com.xquant.databasemanagement.bean.table.TableBean;
import com.xquant.databasemanagement.config.Config;
import com.xquant.databasemanagement.config.ConstantConfig;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;

import java.io.*;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

public class ExportMySQLService {
    Configuration configuration;
    Writer out = null;
    File file = null;


    private ExportMySQLService(){
        URL url =  this.getClass().getResource("/sqlmodel/oracle");
        configuration = new Configuration();
        try {
            configuration.setDirectoryForTemplateLoading(new File("src\\main\\resources\\sqlmodel\\mysql"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }



    /**
     * 导出表脚本
     * @param tableBeanList
     */
    private void exportTableMySQL(List<TableBean> tableBeanList, String operationType) throws IOException, TemplateException {
        if (tableBeanList==null||tableBeanList.size()<=0)
            return;
        try {
            Map<String, Object> dataMap = new HashMap<String, Object>();
            dataMap.put("tableList", tableBeanList);
            Template template = configuration.getTemplate("TableMySQL.ftl");
            File docFile = new File(file.toString() + "\\" + operationType + "TableMySQL.sql");
            out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(docFile)));
            StringWriter stringWriter = new StringWriter();
            template.process(dataMap, stringWriter);
            out.write(Objects.requireNonNull(stringWriter.toString().toUpperCase()));

        }finally {
            if (out!=null){
                out.flush();
                out.close();
                out = null;
            }
        }

    }


    /**
     * 添加列
     * @param tableBeanList
     */
    private void exportAlterTableMySQL(List<TableBean> tableBeanList,String operationType) throws IOException, TemplateException {
        if (tableBeanList==null||tableBeanList.size()<=0)
            return;
        try {
            Map<String, Object> dataMap = new HashMap<String, Object>();
            dataMap.put("tableList", tableBeanList);
            Template template = configuration.getTemplate("AlterTableColumnMySQL.ftl");
            File docFile = new File(file.toString() + "\\" + operationType + "AlterTableMySQL.sql");
            out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(docFile)));
            StringWriter stringWriter = new StringWriter();
            template.process(dataMap, stringWriter);
            out.write(Objects.requireNonNull(stringWriter.toString().toUpperCase()));
        }finally {
            if (out!=null){
                out.flush();
                out.close();
                out = null;
            }
        }

    }


    /**
     * 导出索引
     * @param tableBeanList
     * @throws IOException
     * @throws TemplateException
     */
    private void exportIndexMySQL(List<TableBean> tableBeanList,String operationType) throws IOException, TemplateException {
        if (tableBeanList==null||tableBeanList.size()<=0)
            return;
        try {
            Map<String, Object> dataMap = new HashMap<String, Object>();
            CompareService.getCompareService().classifyIndex(tableBeanList);
            dataMap.put("tableList", tableBeanList);
            dataMap.put("databaseName", Config.databaseName);
            Template template = configuration.getTemplate("IndexMySQL.ftl");
            File docFile = new File(file.toString() + "\\"+ operationType + "IndexMySQL.sql");
            out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(docFile)));
            StringWriter stringWriter = new StringWriter();
            template.process(dataMap, stringWriter);
            out.write(Objects.requireNonNull(stringWriter.toString().toUpperCase()));

            for (TableBean t : tableBeanList) {
                t.groupIndexes = null;
                t.groupUniqueIndexes = null;
            }
        }finally {
            if (out!=null){
                out.flush();
                out.close();
                out = null;
            }
        }
    }

    /**
     * 导出视图、触发器、函数、储存过程及初始化数据脚本
     * @param commonObjectList
     * @param commonType
     */
    private void exportCommonObjectMySQL(List<CommonObject> commonObjectList, String commonType, String operationType) throws IOException, TemplateException {
        if (commonObjectList==null||commonObjectList.size()<=0)
            return;
        try {
            Map<String, Object> dataMap = new HashMap<String, Object>();
            dataMap.put(commonType, commonObjectList);
            Template template = configuration.getTemplate(commonType + ".ftl");
            File docFile = new File(file.toString() + "\\" + operationType + commonType + ".sql");
            out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(docFile)));
            StringWriter stringWriter = new StringWriter();
            template.process(dataMap, stringWriter);
            out.write(Objects.requireNonNull(stringWriter.toString().toUpperCase()));
        }finally {
            if (out!=null){
                out.flush();
                out.close();
                out = null;
            }
        }
    }





    public void exportCompleteMySQL(DatabaseBean databaseBean, File file, String type) throws IOException, TemplateException {
        this.file = file;
        exportCommonObjectMySQL(databaseBean.getBasicDataList(), ConstantConfig.MYSQL_BASICDATA_FTL,type);
        exportTableMySQL(databaseBean.getTableList(),type);
        exportIndexMySQL(databaseBean.getTableList(),type);
        exportCommonObjectMySQL(databaseBean.getViewList(), ConstantConfig.MYSQL_VIEW_FTL,type);
        exportCommonObjectMySQL(databaseBean.getFunctionList(), ConstantConfig.MYSQL_FUNCTION_FTL,type);
        exportCommonObjectMySQL(databaseBean.getProcedureList(), ConstantConfig.MYSQL_PROCEDURE_FTL,type);
        exportCommonObjectMySQL(databaseBean.getTriggerList(), ConstantConfig.MYSQL_TRIGGER_FTL,type);
    }

    public void exportAddMySQL(DatabaseBean databaseBean, File file,String type) throws IOException, TemplateException {
        this.file = file;
        exportAlterTableMySQL(databaseBean.getTableList(),type);
        exportIndexMySQL(databaseBean.getTableList(),type);
    }




    public static ExportMySQLService getExportMySQLService() {
        return exportMySQLService;
    }

    private static ExportMySQLService exportMySQLService = new ExportMySQLService();


}
